<template>
    <n-switch ref="switchRef" v-model:value="themeMode" :rail-style="railStyle" checked-value="light"
        unchecked-value="dark" @update:value="handleTransionView">
        <template #checked-icon>
            <n-icon>
                <SunnyOutline />
            </n-icon>
        </template>
        <template #unchecked-icon>
            <n-icon>
                <MoonOutline />
            </n-icon>
        </template>
    </n-switch>
</template>

<script setup lang='ts'>
import { MoonOutline, SunnyOutline } from '@vicons/ionicons5';
import { CSSProperties } from 'vue';
import { useAppStore } from '@/stores/app';
import { NSwitch } from 'naive-ui';
const appStore = useAppStore();
// 使用 computed 实现双向绑定
const themeMode = computed({
    get: () => appStore.theme,
    set: (value: 'light' | 'dark') => appStore.setThemeMode(value)
});
const switchRef = ref<InstanceType<typeof NSwitch> | null>(null)
const handleTransionView = (e: 'light' | 'dark') => {
    if (!switchRef.value) return

    // 获取原生 DOM 元素
    const el = switchRef.value.$el

    // 获取位置信息
    const rect = el.getBoundingClientRect()
    const transition = document.startViewTransition(() => {
        document.documentElement.dataset.theme = e;
    });
    const x = rect.left;
    const y = rect.top;
    const tragetRadius = Math.hypot(
        Math.max(x, window.innerWidth - x),
        Math.max(y, window.innerHeight - y)
    )
    transition.ready.then(() => {
        document.documentElement.animate(
            {
                clipPath: [`circle(0% at ${x}px ${y}px)`, `circle(${tragetRadius}px at ${x}px ${y}px)`],
            },
            {
                duration: 800,
                pseudoElement: '::view-transition-new(root)'
            }
        )
    })
}
const railStyle = ({
    focused,
    checked
}: {
    focused: boolean
    checked: boolean
}) => {
    const style: CSSProperties = {}
    if (checked) {
        style.background = '#979797'
        if (focused) {
            style.boxShadow = '0 0 0 2px #e7e7e740'
        }
    }
    else {
        style.background = '#11009e'
        if (focused) {
            style.boxShadow = '0 0 0 2px #2080f040'
        }
    }
    return style
}
</script>
<style scoped lang='scss'></style>